From 5563841603eab5ec4ec7516114bc60b647b0664d Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 29 Nov 2016 04:27:21 +0100 Subject: [PATCH] gsk: Add gsk_renderer_new_for_window() and remove gsk_renderer_get_for_display(). This new function returns a realized renderer. Because of that, GSK can catch failures to realize, destroy the renderer and try another one. Or in short: I can finally use GTK on Weston with the nvidia binary drivers again. Signed-off-by: Emmanuele Bassi --- docs/reference/gsk/gsk4-sections.txt | 2 +- gsk/gskrenderer.c | 102 ++++++++++++++++++++------- gsk/gskrenderer.h | 2 +- gtk/gtkwindow.c | 18 +++-- 4 files changed, 85 insertions(+), 39 deletions(-) diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt index 1a1a18d3ea..bc757b568e 100644 --- a/docs/reference/gsk/gsk4-sections.txt +++ b/docs/reference/gsk/gsk4-sections.txt @@ -1,6 +1,6 @@
GskRenderer -gsk_renderer_get_for_display +gsk_renderer_new_for_window gsk_renderer_set_viewport gsk_renderer_get_viewport gsk_renderer_set_scale_factor diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 7d0d8421ed..629551cacf 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -686,23 +686,11 @@ gsk_renderer_get_profiler (GskRenderer *renderer) return priv->profiler; } -/** - * gsk_renderer_get_for_display: - * @display: a #GdkDisplay - * - * Creates an appropriate #GskRenderer instance for the given @display. - * - * Returns: (transfer full) (nullable): a #GskRenderer - * - * Since: 3.90 - */ -GskRenderer * -gsk_renderer_get_for_display (GdkDisplay *display) +static GType +get_renderer_for_env_var (GdkWindow *window) { static const char *use_software; - GType renderer_type = G_TYPE_INVALID; - if (use_software == NULL) { use_software = g_getenv ("GSK_USE_SOFTWARE"); @@ -711,27 +699,87 @@ gsk_renderer_get_for_display (GdkDisplay *display) } if (use_software[0] != '0') - return g_object_new (GSK_TYPE_CAIRO_RENDERER, "display", display, NULL); + return GSK_TYPE_CAIRO_RENDERER; + return G_TYPE_INVALID; +} + +static GType +get_renderer_for_backend (GdkWindow *window) +{ #ifdef GDK_WINDOWING_X11 - if (GDK_IS_X11_DISPLAY (display)) - renderer_type = GSK_TYPE_GL_RENDERER; - else + if (GDK_IS_X11_WINDOW (window)) + return GSK_TYPE_GL_RENDERER; #endif #ifdef GDK_WINDOWING_WAYLAND - if (GDK_IS_WAYLAND_DISPLAY (display)) - renderer_type = GSK_TYPE_GL_RENDERER; - else + if (GDK_IS_WAYLAND_WINDOW (window)) + return GSK_TYPE_GL_RENDERER; #endif - renderer_type = GSK_TYPE_CAIRO_RENDERER; - GSK_NOTE (RENDERER, g_print ("Creating renderer of type '%s' for display '%s'\n", - g_type_name (renderer_type), - G_OBJECT_TYPE_NAME (display))); + return G_TYPE_INVALID; +} + +static GType +get_renderer_fallback (GdkWindow *window) +{ + return GSK_TYPE_CAIRO_RENDERER; +} + +static struct { + GType (* get_renderer) (GdkWindow *window); +} renderer_possibilities[] = { + { get_renderer_for_env_var }, + { get_renderer_for_backend }, + { get_renderer_fallback }, +}; - g_assert (renderer_type != G_TYPE_INVALID); +/** + * gsk_renderer_new_for_window: + * @display: a #GdkDisplay + * + * Creates an appropriate #GskRenderer instance for the given @window. + * + * The renderer will be realized when it is returned. + * + * Returns: (transfer full) (nullable): a #GskRenderer + * + * Since: 3.90 + */ +GskRenderer * +gsk_renderer_new_for_window (GdkWindow *window) +{ + GType renderer_type; + GskRenderer *renderer; + guint i; + + g_return_val_if_fail (GDK_IS_WINDOW (window), NULL); + + for (i = 0; i < G_N_ELEMENTS (renderer_possibilities); i++) + { + renderer_type = renderer_possibilities[i].get_renderer (window); + if (renderer_type == G_TYPE_INVALID) + continue; + + renderer = g_object_new (renderer_type, + "display", gdk_window_get_display (window), + NULL); + + if (gsk_renderer_realize (renderer, window)) + { + GSK_NOTE (RENDERER, g_print ("Using renderer of type '%s' for display '%s'\n", + G_OBJECT_TYPE_NAME (renderer), + G_OBJECT_TYPE_NAME (window))); + return renderer; + } + + GSK_NOTE (RENDERER, g_print ("Failed to realize renderer of type '%s' for window '%s'\n", + G_OBJECT_TYPE_NAME (renderer), + G_OBJECT_TYPE_NAME (window))); + g_object_unref (renderer); + } - return g_object_new (renderer_type, "display", display, NULL); + g_assert_not_reached (); + return NULL; } cairo_surface_t * diff --git a/gsk/gskrenderer.h b/gsk/gskrenderer.h index 031de8e86c..646ba6dedd 100644 --- a/gsk/gskrenderer.h +++ b/gsk/gskrenderer.h @@ -39,7 +39,7 @@ GDK_AVAILABLE_IN_3_90 GType gsk_renderer_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_3_90 -GskRenderer * gsk_renderer_get_for_display (GdkDisplay *display); +GskRenderer * gsk_renderer_new_for_window (GdkWindow *window); GDK_AVAILABLE_IN_3_90 void gsk_renderer_set_viewport (GskRenderer *renderer, diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 89a43e8ffc..0e9678ee21 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -6886,12 +6886,6 @@ gtk_window_realize (GtkWidget *widget) _gtk_widget_get_allocation (widget, &allocation); - if (priv->renderer == NULL) - { - priv->renderer = gsk_renderer_get_for_display (gtk_widget_get_display (widget)); - gsk_renderer_set_scale_factor (priv->renderer, gtk_widget_get_scale_factor (widget)); - } - if (gtk_widget_get_parent_window (widget)) { gdk_window = gdk_window_new_child (gtk_widget_get_parent_window (widget), @@ -6910,7 +6904,8 @@ gtk_window_realize (GtkWidget *widget) popover_realize (popover->widget, popover, window); } - gsk_renderer_realize (priv->renderer, gdk_window); + priv->renderer = gsk_renderer_new_for_window (gdk_window); + gsk_renderer_set_scale_factor (priv->renderer, gtk_widget_get_scale_factor (widget)); return; } @@ -6994,6 +6989,12 @@ gtk_window_realize (GtkWidget *widget) gtk_widget_register_window (widget, gdk_window); gtk_widget_set_realized (widget, TRUE); + if (priv->renderer == NULL) + { + priv->renderer = gsk_renderer_new_for_window (gdk_window); + gsk_renderer_set_scale_factor (priv->renderer, gtk_widget_get_scale_factor (widget)); + } + if (priv->client_decorated && priv->type == GTK_WINDOW_TOPLEVEL) { const gchar *cursor_names[8] = { @@ -7106,9 +7107,6 @@ gtk_window_realize (GtkWidget *widget) } check_scale_changed (window); - - /* Renderer */ - gsk_renderer_realize (priv->renderer, gdk_window); } static void -- 2.30.2